package com.yswee.mallnavi.activity.base;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import com.yswee.framework.R;
import com.yswee.framework.manager.WindowManager;
import com.yswee.framework.utils.FileUtils;
import com.yswee.framework.utils.ImageUtils;
import com.yswee.framework.utils.PackageUtils;
import com.yswee.framework.utils.RomUtils;
import com.yswee.framework.utils.UriUtils;

import android.Manifest;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

/**
 * 选择图片页面
 * @author Administrator
 *
 */
public class PhotoChooserActivity extends BaseActivity {

	public static final int REQUESTCODE_PERMISSION = 1213;
	public static final String EXTENSION = ".jpg";

	public static final String INTENT_ACTION = "action";
	public static final String INTENT_CROP = "crop";
	public static final String INTENT_CROPWIDTH = "cropwidth";
	public static final String INTENT_CROPHEIGHT = "cropheight";
	public static final String INTENT_ASPECTX = "aspectx";
	public static final String INTENT_ASPECTY = "aspecty";
	public static final String INTENT_COMPRESS = "compress";
	public static final String INTENT_COMPRESSWIDTH = "compresswidth";
	public static final String INTENT_COMPRESSHEIGHT = "compressheight";
	public static final String INTENT_COMPRESSFILESIZE = "compressfilesize";

	public static final String INTENT_URI = "data";
	public static final String INTENT_URIS = "datas";
	protected static final String INTENT_URICROP = "uricrop";
	protected static final String INTENT_URICROP_F = "uricrop_f";
	protected static final String INTENT_URICAMERA = "uricamera";
	protected static final String INTENT_URICAMERA_F = "uricamera_f";

	public static final int RESULTCODE_OK = 1;
	public static final int RESULTCODE_DEL = 2;
	public static final int RESULTCODE_CANCEL = 3;

	public static final int ACTION_NONE = 0;
	public static final int ACTION_ALBUM = 1;
	public static final int ACTION_CAMERA = 2;

	protected static final int REQUESTCODE_PICKPHOTO_CAMERA = 2;
	protected static final int REQUESTCODE_PICKPHOTO_ALBUM = 3;
	protected static final int REQUESTCODE_CROPPHOTO = 4;
	protected static final int HANLDER_WHAT_COMPRESFINISH = 1;

	protected int action;
	protected boolean crop;
	protected boolean encrpt;
	protected int cropWidth = 500;
	protected int cropHeight = 500;
	protected int aspectX = 1;
	protected int aspectY = 1;
	protected boolean compress;
	protected int compressWidth;
	protected int compressHeight;
	protected int compressFileSize = 500 * 1024;

	protected Uri uriCrop;
	protected Uri uriCropF;
	protected Uri uriCamera;
	protected Uri uriCameraF;

	protected View vwRoot;
	protected Button btnTake;
	protected Button btnPick;
	protected Button btnCancel;
	protected Dialog compressDialog;

	@Override
	protected boolean isDialogTheme() {
		return true;
	}

	protected Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
				case HANLDER_WHAT_COMPRESFINISH: {
					if (compressDialog != null) {
						compressDialog.dismiss();
					}
					Intent intent = new Intent();
					if (msg.obj != null) {
						Uri uri = (Uri) msg.obj;
						intent.putExtra(INTENT_URI, uri);
					}
					onSetResultCompress(intent);
					break;
				}
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(getContentViewResId());
	}

	protected int getContentViewResId() {
		return R.layout.activity_photochooser;
	}

	@Override
	protected void onQueryArguments(Intent intent) {
		super.onQueryArguments(intent);
		action = intent.getIntExtra(INTENT_ACTION, ACTION_NONE);
		crop = intent.getBooleanExtra(INTENT_CROP, false);
		cropWidth = intent.getIntExtra(INTENT_CROPWIDTH, cropWidth);
		cropHeight = intent.getIntExtra(INTENT_CROPHEIGHT, cropHeight);
		aspectX = intent.getIntExtra(INTENT_ASPECTX, aspectX);
		aspectY = intent.getIntExtra(INTENT_ASPECTY, aspectY);
		compress = intent.getBooleanExtra(INTENT_COMPRESS, true);
		compressWidth = intent.getIntExtra(INTENT_COMPRESSWIDTH, (int) (WindowManager.get().getScreenWidth() * 1.5));
		compressHeight = intent.getIntExtra(INTENT_COMPRESSHEIGHT, (int) (WindowManager.get().getScreenHeight() * 1.5));
		compressFileSize = intent.getIntExtra(INTENT_COMPRESSFILESIZE, compressFileSize);
	}

	@Override
	protected void onFindView() {
		super.onFindView();
		vwRoot = findViewById(R.id.root);
		btnTake = (Button) findViewById(R.id.btncamera);
		btnPick = (Button) findViewById(R.id.btnalbum);
		btnCancel = (Button) findViewById(R.id.btncancel);
	}

	@Override
	protected void onBindListener() {
		super.onBindListener();
		if (vwRoot != null) {
			vwRoot.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					finish();
				}
			});
		}
		if(btnTake != null) {
			btnTake.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					onCameraClicked();
				}
			});
		}
		if(btnPick != null) {
			btnPick.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					onAlbumClicked();
				}
			});
		}
		if(btnCancel != null) {
			btnCancel.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					finish();
				}
			});
		}
	}

	@Override
	protected void onApplyData() {
		super.onApplyData();
		if (requestPermission()) {
			applyAction();
		}
	}

	@Override
	public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
		super.onRequestPermissionsResult(requestCode, permissions, grantResults);
		if (requestCode == REQUESTCODE_PERMISSION) {
			for (int i = 0; i < permissions.length; i++) {
				if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
					finish();
					break;
				}
			}
			applyAction();
		}
	}

	protected void applyAction() {
		if(action == ACTION_ALBUM) {
			btnPick.performClick();
			vwRoot.setVisibility(View.GONE);
		} else if(action == ACTION_CAMERA) {
			btnTake.performClick();
			vwRoot.setVisibility(View.GONE);
		}
	}

	protected boolean requestPermission() {
		String[] permissions = new String[] {
				Manifest.permission.WRITE_EXTERNAL_STORAGE,
				Manifest.permission.READ_EXTERNAL_STORAGE,
				Manifest.permission.CAMERA,
				Manifest.permission.VIBRATE
		};
		ArrayList<String> array = new ArrayList<String>();
		for (String permission : permissions) {
			if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
				//如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
				if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
					//这里可以写个对话框之类的项向用户解释为什么要申请权限，并在对话框的确认键后续再次申请权限
					array.add(permission);
				} else {
					//申请权限，字符串数组内是一个或多个要申请的权限，1是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
					array.add(permission);
				}
			}
		}
		if (array.size() > 0) {
			String[] needs = new String[array.size()];
			array.toArray(needs);
			ActivityCompat.requestPermissions(this, needs, REQUESTCODE_PERMISSION);
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 点击相机按钮
	 */
	protected void onCameraClicked() {
		try {
			File file = new File(getCachePicFolderName(), getCameraPicFileName());
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
				uriCameraF = Uri.fromFile(file);
				uriCamera = FileProvider.getUriForFile(this,
						PackageUtils.getPackageName(this) + ".fileProvider", file);
			}else{
				uriCameraF = Uri.fromFile(file);
				uriCamera = Uri.fromFile(file);
			}
			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
			intent.putExtra(MediaStore.EXTRA_OUTPUT, uriCamera);
			startActivityForResult(intent, REQUESTCODE_PICKPHOTO_CAMERA);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 点击相册按钮
	 */
	protected void onAlbumClicked() {
		try {
			Intent intent = new Intent(Intent.ACTION_PICK, null);
			intent.setDataAndType(MediaStore.Images.Media.
					EXTERNAL_CONTENT_URI, "image/*");
			startActivityForResult(intent, REQUESTCODE_PICKPHOTO_ALBUM);
		} catch (ActivityNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 默认图片缓存文件夹目录
	 * @return
	 */
	public static String CachePicFolder() {
		return FileUtils.getCachePath() + File.separator + FileUtils.PHOTOCACHEPATH + File.separator;
	}

	/**
	 * 图片缓存文件夹
	 * @return
	 */
	protected String getCachePicFolderName() {
		String folder = CachePicFolder();
		File file = new File(folder);
		if(!file.exists())
			file.mkdirs();
		return folder;
	}

	/**
	 * 拍照缓存文件名称
	 * @return
	 */
	protected String getCameraPicFileName() {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssssss");
		StringBuilder sBuilder = new StringBuilder();
		sBuilder.append("picture").append(format.format(new Date())).append(EXTENSION);
		return sBuilder.toString();
	}

	/**
	 * 裁剪缓存文件名称
	 * @return
	 */
	protected String getCropPicFileName() {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssssss");
		StringBuilder sBuilder = new StringBuilder();
		sBuilder.append("crop").append(format.format(new Date())).append(EXTENSION);
		return sBuilder.toString();
	}

	/**
	 * 裁剪缓存文件名称
	 * @return
	 */
	protected String getCompressPicFileName() {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssssss");
		StringBuilder sBuilder = new StringBuilder();
		sBuilder.append("compress").append(format.format(new Date())).append(EXTENSION);
		return sBuilder.toString();
	}

	/**
	 * 压缩中等待进度条样式
	 * @return
	 */
	protected int getCompressDialogResId() {
		return R.layout.view_compress;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		onSetResultCancel();
		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode != RESULT_OK) {
			if (action != ACTION_NONE) {
				finish();
			}
			return;
		}
		if (requestCode == REQUESTCODE_PICKPHOTO_CAMERA) {
			Uri uri = null, uri_f = null;
			uri = uriCamera;
			uri_f = uriCameraF;
			if (uri != null && uri_f != null) {
				if (crop) {
					startActivityForCropPhoto(uri, uri_f, true);
				} else {
					if (compress) {
						startActivityForCompressPhoto(uri, uri_f);
					} else {
						Intent intent = new Intent();
						intent.putExtra(INTENT_URI, uri_f);
						onSetResultFinish(intent);
					}
				}
			}
		} else if (requestCode == REQUESTCODE_PICKPHOTO_ALBUM) {
			Uri uri = null, uri_f = null;
			if(data != null && data.getData() != null){
				uri = data.getData();
				uri_f = uri;
			}
			if(uri != null && uri_f != null) {
				if(crop) {
					startActivityForCropPhoto(uri, uri_f, false);
				} else {
					if(compress) {
						startActivityForCompressPhoto(uri, uri_f);
					} else {
						Intent intent = new Intent();
						intent.putExtra(INTENT_URI, uri_f);
						onSetResultFinish(intent);
					}
				}
			}
		} else if(requestCode == REQUESTCODE_CROPPHOTO) {
			if (uriCamera != null) {
				FileUtils.removeFile(PhotoChooserActivity.this, uriCamera.getPath());
			}
			if (uriCameraF != null) {
				FileUtils.removeFile(PhotoChooserActivity.this, uriCameraF.getPath());
			}
			if(compress) {
				if (RomUtils.isMiui()) {
					uriCrop = FileProvider.getUriForFile(this,
							PackageUtils.getPackageName(this) + ".fileProvider",
							new File(uriCropF.getPath()));
				}
				startActivityForCompressPhoto(uriCrop, uriCropF);
			} else {
				Intent intent = new Intent();
				intent.putExtra(INTENT_URI, uriCropF);
				onSetResultCrop(intent);
			}
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if(uriCrop != null) {
			outState.putString(INTENT_URICROP, uriCrop.toString());
		}
		if(uriCropF != null) {
			outState.putString(INTENT_URICROP_F, uriCropF.toString());
		}
		if(uriCamera != null) {
			outState.putString(INTENT_URICAMERA, uriCamera.toString());
		}
		if(uriCameraF != null) {
			outState.putString(INTENT_URICAMERA_F, uriCameraF.toString());
		}
		outState.putBoolean(INTENT_CROP, crop);
		outState.putInt(INTENT_CROPWIDTH, cropWidth);
		outState.putInt(INTENT_CROPHEIGHT, cropHeight);
		outState.putInt(INTENT_ASPECTX, aspectX);
		outState.putInt(INTENT_ASPECTY, aspectY);
		outState.putBoolean(INTENT_COMPRESS, compress);
		outState.putInt(INTENT_COMPRESSWIDTH, compressWidth);
		outState.putInt(INTENT_COMPRESSHEIGHT, compressHeight);
		outState.putInt(INTENT_COMPRESSFILESIZE, compressFileSize);
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		String uricrop = savedInstanceState.getString(INTENT_URICROP);
		if(!TextUtils.isEmpty(uricrop)) {
			uriCrop = Uri.parse(uricrop);
		}
		String uricropf = savedInstanceState.getString(INTENT_URICROP_F);
		if(!TextUtils.isEmpty(uricropf)) {
			uriCropF = Uri.parse(uricropf);
		}
		String uricamera = savedInstanceState.getString(INTENT_URICAMERA);
		if(!TextUtils.isEmpty(uricamera)) {
			uriCamera = Uri.parse(uricamera);
		}
		String uricameraf = savedInstanceState.getString(INTENT_URICAMERA_F);
		if(!TextUtils.isEmpty(uricameraf)) {
			uriCameraF = Uri.parse(uricameraf);
		}
		crop = savedInstanceState.getBoolean(INTENT_CROP, crop);
		cropWidth = savedInstanceState.getInt(INTENT_CROPWIDTH, cropWidth);
		cropHeight = savedInstanceState.getInt(INTENT_CROPHEIGHT, cropHeight);
		aspectX = savedInstanceState.getInt(INTENT_ASPECTX, aspectX);
		aspectY = savedInstanceState.getInt(INTENT_ASPECTY, aspectY);
		compress = savedInstanceState.getBoolean(INTENT_COMPRESS, compress);
		compressWidth = savedInstanceState.getInt(INTENT_COMPRESSWIDTH, compressWidth);
		compressHeight = savedInstanceState.getInt(INTENT_COMPRESSHEIGHT, compressHeight);
		compressFileSize = savedInstanceState.getInt(INTENT_COMPRESSFILESIZE, compressFileSize);
	}

	protected void startActivityForCropPhoto(final Uri uri, final Uri uri_f, final boolean fromCamera) {
		Intent intent = new Intent("com.android.camera.action.CROP");
		intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
		intent.putExtra("noFaceDetection", true);
		intent.putExtra("return-data", false);
		intent.putExtra("scale", true);
		intent.putExtra("crop", "true");
		intent.setDataAndType(uri, "image/*");
		if(aspectX > 0)
			intent.putExtra("aspectX", aspectX);
		if(aspectY > 0)
			intent.putExtra("aspectY", aspectY);
		intent.putExtra("outputX", cropWidth);
		intent.putExtra("outputY", cropHeight);
		if (fromCamera) {
			intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
		}
		File cropFile = new File(getCachePicFolderName(), getCropPicFileName());
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
			uriCropF = Uri.fromFile(cropFile);
			if (RomUtils.isMiui()) {
				uriCrop = UriUtils.getImageContentUri(this, cropFile);
			} else {
				uriCrop = FileProvider.getUriForFile(this,
						PackageUtils.getPackageName(this) + ".fileProvider", cropFile);
			}
		}else{
			uriCropF = Uri.fromFile(cropFile);
			uriCrop = Uri.fromFile(cropFile);
		}
		intent.putExtra(MediaStore.EXTRA_OUTPUT, uriCrop);
		startActivityForResult(intent, REQUESTCODE_CROPPHOTO);
	}

	protected void startActivityForCompressPhoto(final Uri uri, final Uri uri_f) {
		if(compressDialog == null) {
			View root = LayoutInflater.from(this).inflate(getCompressDialogResId(), null);
			compressDialog = new Dialog(this, R.style.MDialogStyle);
			compressDialog.setCancelable(false);
			compressDialog.setCanceledOnTouchOutside(false);
			compressDialog.setContentView(root,
					new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							LinearLayout.LayoutParams.MATCH_PARENT
					)
			);
		}
		compressDialog.show();
		new Thread(new Runnable() {
			@Override
			public void run() {
				Uri uriresult = uri;
				Uri uritemp = compressBitmap(getBaseContext(), uri);
				if(uritemp != null) {
					try {
						Context context = PhotoChooserActivity.this;
						FileUtils.removeFile(context, uri.getPath());
						FileUtils.removeFile(context, uri_f.getPath());
					} catch (Exception e) {
						e.printStackTrace();
					}
					uriresult = uritemp;
				}
				Message msg = mHandler.obtainMessage();
				msg.what = HANLDER_WHAT_COMPRESFINISH;
				msg.obj = uriresult;
				mHandler.sendMessage(msg);
			}
		}).start();
	}

	protected void startActivityForCompressPhoto(final Bitmap bitmap) {
		if(compressDialog == null) {
			View root = LayoutInflater.from(this).inflate(getCompressDialogResId(), null);
			compressDialog = new Dialog(this, R.style.MDialogStyle);
			compressDialog.setCancelable(false);
			compressDialog.setCanceledOnTouchOutside(false);
			compressDialog.setContentView(root,
					new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							LinearLayout.LayoutParams.MATCH_PARENT
					)
			);
		}
		compressDialog.show();
		new Thread(new Runnable() {
			@Override
			public void run() {
				Uri uriresult = compressBitmap(getBaseContext(), bitmap);
				Message msg = mHandler.obtainMessage();
				msg.what = HANLDER_WHAT_COMPRESFINISH;
				msg.obj = uriresult;
				mHandler.sendMessage(msg);
			}
		}).start();
	}

	protected void onSetResultCrop(Intent intent) {
		setResult(RESULTCODE_OK, intent);
		finish();
	}

	protected void onSetResultCompress(Intent intent) {
		setResult(RESULTCODE_OK, intent);
		finish();
	}

	protected void onSetResultFinish(Intent intent) {
		setResult(RESULTCODE_OK, intent);
		finish();
	}

	protected void onSetResultCancel() {
		setResult(RESULT_CANCELED);
		finish();
	}

	protected void onSetResultDelete() {
		setResult(RESULTCODE_DEL);
		finish();
	}

	public static Uri decodeUri(Context context, Intent intent) {
		try {
			Uri uri = intent.getParcelableExtra(INTENT_URI);
			if (uri != null) {
				return uri;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static ArrayList<Uri> decodeUris(Context context, Intent intent) {
		try {
			@SuppressWarnings("unchecked")
			ArrayList<Uri> uris = (ArrayList<Uri>) intent.getSerializableExtra(INTENT_URIS);
			if (uris != null) {
				return uris;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Bitmap decodeBitmap(Context context, Intent intent) {
		try {
			Uri uri = intent.getParcelableExtra(INTENT_URI);
			if (uri != null) {
				Bitmap bitmap = BitmapFactory.decodeStream(context.
						getContentResolver().openInputStream(uri));
				return bitmap;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	protected Uri compressBitmap(Context context, Uri uri) {
		int degree = 0;
		try {
			degree = ImageUtils.getBitmapDegree(UriUtils.getPath(context, uri));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Bitmap bitmap = ImageUtils.compressBitmapByBound(context,
				uri, compressWidth, compressHeight);
		if(degree > 0) {
			bitmap = ImageUtils.rotateBitmap(bitmap, degree);
		}
		if(bitmap != null) {
			Uri newuri = null;
			byte[] bytes = ImageUtils.compressBitmapByQuanlity(bitmap, compressFileSize);
			File f = new File(getCachePicFolderName(), getCompressPicFileName());
			boolean s = FileUtils.saveBytes2File(bytes, f.getPath());
			if(s) {
				newuri = Uri.fromFile(f);
			}
			if(bitmap != null) {
				if(!bitmap.isRecycled()) {
					bitmap.recycle();
				}
				bitmap = null;
			}
			return newuri;
		}
		return null;
	}

	protected Uri compressBitmap(Context context, Bitmap bitmap_o) {
		Bitmap bitmap = ImageUtils.compressBitmapByBound(context,
				bitmap_o, compressWidth, compressHeight);
		if(bitmap != null) {
			byte[] bytes = ImageUtils.compressBitmapByQuanlity(bitmap, compressFileSize);
			Uri uri = null;
			File f = new File(getCachePicFolderName(), getCompressPicFileName());
			boolean s = FileUtils.saveBytes2File(bytes, f.getPath());
			if(s) {
				uri = Uri.fromFile(f);
			}
			if(bitmap != null) {
				if(!bitmap.isRecycled()) {
					bitmap.recycle();
				}
				bitmap = null;
			}
			return uri;
		}
		return null;
	}

}

